<template>
  <div class="upload-file">
    <el-upload
        class="upload-file-uploader"
        action=""
        :file-list="fileList"
        :limit="limit"
        :http-request="handleHttpRequest"
        :on-exceed="handleExceed"
        :on-remove="handleRemoveFile"
    >
      <!-- 上传按钮 -->
      <el-button size="mini" type="primary">选取文件</el-button>
      <!-- 上传提示 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        请上传
        <template v-if="fileSize">
          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
        </template>
        <template v-if="fileType">
          格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
        </template>
        的文件
      </div>
    </el-upload>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: "ShardUpload",
  props: {
    value: [String, Object, Array],
    nameList: {
      type: Array,
      default: () => [],
    },
    limit: {
      type: Number,
      default: 5,
    },
    fileSize: {
      type: Number,
      default: 500,
    },
    fileType: {
      type: [Array, Boolean],
      default: () => ["doc", "docx", "xls", "xlsx", "ppt", "txt", "pdf"],
    },
    isShowTip: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      fileList: [],
      fileUploadChunkQueue: {},
    };
  },
  computed: {
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          let temp = 1;
          const list = Array.isArray(val) ? val : this.value.split(",");
          this.fileList = list.map((item, index) => {
            if (typeof item === "string") {
              item = { name: this.nameList[index] || item, url: item };
            }
            item.uid = item.uid || new Date().getTime() + temp++;
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    handleRemoveFile(uploadFile) {
      const index = this.fileList.findIndex((i) => i.uid === uploadFile.uid);
      if (index !== -1) {
        this.fileList.splice(index, 1);
        this.$emit("input", this.listToString(this.fileList));
      }
      const queueObject = this.fileUploadChunkQueue[uploadFile.uid];
      if (queueObject) {
        queueObject.stop();
        this.fileUploadChunkQueue[uploadFile.uid] = undefined;
      }
    },
    async handleHttpRequest(options) {
      const file = options.file;

      // 校检文件类型
      if (this.fileType) {
        const fileName = file.name.split(".");
        const fileExt = fileName[fileName.length - 1].toLowerCase();
        const isTypeOk = this.fileType.includes(fileExt);
        if (!isTypeOk) {
          console.error(`文件格式不正确, 请上传 ${this.fileType.join("/")}`);
          if (options.onError) {
            options.onError(new Error(`文件格式不正确, 请上传 ${this.fileType.join("/")}`));
          }
          return;
        }
      }

      // 校验文件大小
      if (file.size > this.fileSize * 1024 * 1024) {
        console.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
        if (options.onError) {
          options.onError(new Error(`上传文件大小不能超过 ${this.fileSize} MB!`));
        }
        return;
      }

      // 开始文件上传
      const formData = new FormData();
      formData.append('file', file);

      try {
        const response = await axios.post('/oss/minio/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        });
        const { code, data, msg } = response;

        if (code === 200) {
          const successFile = {
            name: file.name,
            url: data.url,
            fileSize: file.size,
          };
          this.fileList.push(successFile);
          this.$emit('input', this.listToString(this.fileList));
          this.$emit('uploadSuccess', successFile);
          if (options.onSuccess) {
            options.onSuccess(successFile);
          }
          return data.url;
        } else {
          console.error(msg || '上传失败1111');
          if (options.onError) {
            options.onError(new Error(msg || '上传失败'));
          }
        }
      } catch (error) {
        console.error('上传错误:', error.message);
        if (options.onError) {
          options.onError(error);
        }
      }
    },



    listToString(list, separator) {
      let strs = "";
      separator = separator || ",";
      for (let i in list) {
        strs += list[i].url + separator;
      }
      return strs != "" ? strs.substr(0, strs.length - 1) : "";
    },
    handleExceed() {
      this.$notify({
        title: "文件数量超限",
        type: "error",
        message: `上传文件数量不能超过 ${this.limit} 个!`,
      });
    },
  },
};
</script>
